package AITest;

import java.awt.*;
import java.util.*;

public class MyAI {
	
	private int Scale;
	private int[][][] WeightBox=new int[15][15][4];
	private int[][] MergeBox=new int[15][15];
	private int[] match=new int[5];
	private int[] calWeight=new int[5];
	private int[] calPriority=new int[5];
	private boolean competitor;
	
	private static int[][] state=new int[][]
	{
	{0,0,0,0,0},//  -----   0
	{0,0,0,0,1},//	----0	1
	{0,0,0,1,0},//	---0-	2
	{0,0,0,1,1},//	---00	3
	{0,0,1,0,0},//	--0--	4
	{0,0,1,0,1},//	--0-0	5
	{0,0,1,1,0},//	--00-	6
	{0,0,1,1,1},//	--000	7
	{0,1,0,0,0},//	-0---	8
	{0,1,0,0,1},//	-0--0	9
	{0,1,0,1,0},//	-0-0-	10
	{0,1,0,1,1},//	-0-00	11
	{0,1,1,0,0},//	-00--	12
	{0,1,1,0,1},//	-00-0	13
	{0,1,1,1,0},//	-000-	14
	{0,1,1,1,1},//	-0000	15
	{1,0,0,0,0},//	0----	16
	{1,0,0,0,1},//	0---0	17
	{1,0,0,1,0},//	0--0-	18
	{1,0,0,1,1},//	0--00	19
	{1,0,1,0,0},//	0-0--	20
	{1,0,1,0,1},//	0-0-0	21
	{1,0,1,1,0},//	0-00-	22
	{1,0,1,1,1},//	0-000	23
	{1,1,0,0,0},//	00---	24
	{1,1,0,0,1},//	00--0	25
	{1,1,0,1,0},//	00-0-	26
	{1,1,0,1,1},//	00-00	27
	{1,1,1,0,0},//	000--	28
	{1,1,1,0,1},//	000-0	29
	{1,1,1,1,0},//	0000-	30		
	};
	
	private static int[][] weight=new int[][]
	{	
	{1,1,1,1,1},//  -----   0
	{12,12,12,2,0},//	----0	1
	{12,12,2,0,2},//	---0-	2
	{13,3,3,0,0},//	---00	3
	{12,2,0,2,12},//	--0--	4
	{13,3,0,3,0},//	--0-0	5
	{3,3,0,0,3},//	--00-	6
	{14,4,0,0,0},//	--000	7
	{2,0,2,12,12},//	-0---	8
	{13,0,3,3,0},//	-0--0	9
	{3,0,3,0,3},//	-0-0-	10
	{14,0,4,0,0},//	-0-00	11
	{3,0,0,3,3},//	-00--	12
	{14,0,0,4,0},//	-00-0	13
	{4,0,0,0,4},//	-000-	14
	{5,0,0,0,0},//	-0000	15
	{0,2,12,12,12},//	0----	16
	{0,13,13,13,0},//	0---0	17
	{0,3,3,0,13},//	0--0-	18
	{0,14,4,0,0},//	0--00	19
	{0,3,0,3,13},//	0-0--	20
	{0,4,0,4,0},//	0-0-0	21
	{0,4,0,0,14},//	0-00-	22
	{0,5,0,0,0},//	0-000	23
	{0,0,3,3,13},//	00---	24
	{0,0,4,14,0},//	00--0	25
	{0,0,4,0,14},//	00-0-	26
	{0,0,5,0,0},//	00-00	27
	{0,0,0,4,14},//	000--	28
	{0,0,0,5,0},//	000-0	29
	{0,0,0,0,5},//	0000-	30		
	};
	
	public MyAI(int Scale){
		
		this.Scale=Scale;
	}
	
	public void testOutput(){
		
		System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
		
		for(int i=0;i<15;i++){		
			
			for(int j=0;j<15;j++){
				
				System.out.print(MergeBox[i][j]+"@");
			}
			
			System.out.println();
		}
		
		System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
	}
	
	
	public Point makeStrategy(int[][] ChessBox, int player){
            
            for(int i=0;i<Scale;i++){
            
                for(int j=0;j<Scale;j++){
                
                    MergeBox[i][j]=0;
                    
                    for(int k=0;k<4;k++){
                    
                        WeightBox[i][j][k]=0;
                    }
                }
            }
		
		Point result=generateStrategy(ChessBox,player);
		
		//testOutput();
		
		System.out.println(result.x+"@"+result.y);
		
		return result;
	}
	
	public Point generateStrategy(int[][] ChessBox, int player){
		
		calChessBoxWeight(ChessBox,player);
		
		ArrayList<int[]> choice=new ArrayList<int[]>();
		
		int Standard=0;
		
		for(int i=0;i<Scale;i++){
			
			for(int j=0;j<Scale;j++){
				
				if(MergeBox[i][j]>Standard){
					
					choice.clear();
					Standard=MergeBox[i][j];
					
					int[] point=new int[3];
					
					point[0]=i;
					point[1]=j;
					point[2]=MergeBox[i][j];
					
					choice.add(point);
				}else if(MergeBox[i][j]==Standard){
					
					int[] point=new int[3];
					
					point[0]=i;
					point[1]=j;
					point[2]=MergeBox[i][j];
					
					choice.add(point);
				}
			}
		}
		
		long time = Calendar.getInstance().getTimeInMillis();			
		Random generator=new Random();		
		generator.setSeed(time);		
		int shuffle=(int)(generator.nextDouble()*choice.size());
		int[] result=choice.get(shuffle);
		Point position=new Point(result[0],result[1]);
		
		return position;
	}
	
	public void calChessBoxWeight(int[][] ChessBox, int player){
		
		competitor=false;
		
		for(int i=0;i<Scale;i++){
			
			for(int j=0;j<Scale;j++){
				
				calPointWeight(ChessBox,player,i,j);
			}
		}
		
		for(int i=0;i<Scale;i++){
			
			for(int j=0;j<Scale;j++){
				
				int total=0;
				
				for(int k=0;k<4;k++){
					
					total+=WeightBox[i][j][k];
					WeightBox[i][j][k]=0;
				}
				
				if(ChessBox[i][j]==0){
					
					MergeBox[i][j]=Math.max(MergeBox[i][j],total);
				}
				
								
			}
		}
		
		competitor=true;		
		
		
		for(int i=0;i<Scale;i++){
			
			for(int j=0;j<Scale;j++){
				
				calPointWeight(ChessBox,-player,i,j);
			}
		}
		
		for(int i=0;i<Scale;i++){
			
			for(int j=0;j<Scale;j++){
				
				int total=0;
				
				for(int k=0;k<4;k++){
					
					total+=WeightBox[i][j][k];
					WeightBox[i][j][k]=0;
				}
				
				if(ChessBox[i][j]==0){
					
					MergeBox[i][j]=Math.max(MergeBox[i][j],total);
				}				
			}
		}
	}
	
	public void calPointWeight(int[][] ChessBox, int player,int x,int y){
		
		if(x-2<0||x+2>=Scale||y-2<0||y+2>=Scale){
			
			return;
			//return 0;
		}
		
		boolean isAlive;		
		
		//竖直		
			
			if(x-3<0||x+3>=Scale){				
				
				
			}else{
				
				isAlive=true;
				
				for(int i=0;i<5;i++){
					
					match[i]=ChessBox[x-2+i][y];
				}
				
				if(ChessBox[x-3][y]!=0||ChessBox[x+3][y]!=0){
					isAlive=false;
				}
				
				matchPoint(match,player,x,y,isAlive);
				
				for(int i=0;i<5;i++){
					
					WeightBox[x-2+i][y][0]=Math.max(WeightBox[x-2+i][y][0], calPriority[i]);
				}
				
			}
		
		
		//水平
			
			if(y-3<0||y+3>=Scale){				
				
				
			}else{
				
				isAlive=true;
				
				for(int i=0;i<5;i++){
					
					match[i]=ChessBox[x][y-2+i];
				}
				
				if(ChessBox[x][y-3]!=0||ChessBox[x][y+3]!=0){
					isAlive=false;
				}
				
				matchPoint(match,player,x,y,isAlive);				
				
				for(int i=0;i<5;i++){				
					
					WeightBox[x][y-2+i][1]=Math.max(WeightBox[x][y-2+i][1], calPriority[i]);
				}
				
			}
		//左斜
			
			if(x-3<0||y-3<0||x+3>=Scale||y+3>=Scale){				
				
				
			}else{
				
				isAlive=true;
				
				for(int i=0;i<5;i++){
					
					match[i]=ChessBox[x-2+i][y-2+i];
				}
				
				if(ChessBox[x-3][y-3]!=0||ChessBox[x+3][y+3]!=0){
					isAlive=false;
				}
				
				matchPoint(match,player,x,y,isAlive);
				
				for(int i=0;i<5;i++){
					
					WeightBox[x-2+i][y-2+i][2]=Math.max(WeightBox[x-2+i][y-2+i][2], calPriority[i]);
				}
				
			}
		//右斜
			
			if(x-3<0||y-3<0||x+3>=Scale||y+3>=Scale){				
				
				
			}else{
				
				isAlive=true;
				
				for(int i=0;i<5;i++){
					
					match[i]=ChessBox[x+2-i][y-2+i];
				}
				
				if(ChessBox[x+3][y-3]!=0||ChessBox[x-3][y+3]!=0){
					isAlive=false;
				}
				
				matchPoint(match,player,x,y,isAlive);
				
				for(int i=0;i<5;i++){
					
					WeightBox[x+2-i][y-2+i][3]=Math.max(WeightBox[x+2-i][y-2+i][3], calPriority[i]);
				}
				
			}
		
		//return 0;
		
	}
	
	public void matchPoint(int[] match,int player,int x,int y,boolean isAlive){
		
		for(int i=0;i<5;i++){
			
			calPriority[i]=0;
		}
		
		boolean isMatch=true;
		
		for(int i=0;i<state.length;i++){
			
			isMatch=true;
			
			for(int j=0;j<5;j++){
				
				if(match[j]!=state[i][j]*player){	
					
					isMatch=false;
					break;
				}
			}
			
			if(isMatch){				
				
				calWeight=weight[i];
				
				if(isAlive){
					
					for(int j=0;j<5;j++){
						
						calPriority[j]=getWeight(calWeight[j]);						
					}
				}else{
					
					for(int j=0;j<5;j++){
						
						calPriority[j]=getWeight(-calWeight[j]);						
					}
				}
				
				return;
			}
		}		
	}
	
	public int getWeight(int pri){
		
		Priority w=new Priority();
		
		if(competitor){
			pri+=100;
		}

		switch(pri){
		
		case -1:
			return w.getPriority("d1");
			
		case -2:
			return w.getPriority("d2");		
			
		case -3:
			return w.getPriority("d3");	
			
		case -4:
			return w.getPriority("d4");	
			
		case -5:
			return w.getPriority("d5");
			
		case 1:
			return w.getPriority("a1");
			
		case 2:
			return w.getPriority("a2");
			
		case 3:
			return w.getPriority("a3");		
			
		case 4:
			return w.getPriority("a4");
		
		case 5:
			return w.getPriority("a5");	
			
		case -11:
			return w.getPriority("d1")-16;
			
		case -12:
			return w.getPriority("d2")-50;		
			
		case -13:
			return w.getPriority("d3")-500;	
			
		case -14:
			return w.getPriority("d4")-6000;	
			
		case -15:
			return w.getPriority("d5");
			
		case 11:
			return w.getPriority("a1");
			
		case 12:
			return w.getPriority("a2")-300;
			
		case 13:
			return w.getPriority("a3")-4000;		
			
		case 14:
			return w.getPriority("a4")-30000;
		
		case 15:
			return w.getPriority("a5");	
			
			
			
			
		case 99:
			return w.getPriority("d1")-6;
			
		case 98:
			return w.getPriority("d2")-30;		
			
		case 97:
			return w.getPriority("d3")-150;	
			
		case 96:
			return w.getPriority("d4")-800;	
			
		case 95:
			return w.getPriority("d5")-2000000;
			
		case 101:
			return w.getPriority("a1");
			
		case 102:
			return w.getPriority("a2")-180;
			
		case 103:
			return w.getPriority("a3")-3000;		
			
		case 104:
			return w.getPriority("a4")-10000;
		
		case 105:
			return w.getPriority("a5")-2000000;	
			
		case 89:
			return w.getPriority("d1")-18;
			
		case 88:
			return w.getPriority("d2")-60;		
			
		case 87:
			return w.getPriority("d3")-600;	
			
		case 86:
			return w.getPriority("d4")-7000;	
			
		case 85:
			return w.getPriority("d5");
			
		case 111:
			return w.getPriority("a1");
			
		case 112:
			return w.getPriority("a2")-320;
			
		case 113:
			return w.getPriority("a3")-5000;		
			
		case 114:
			return w.getPriority("a4")-35000;
		
		case 115:
			return w.getPriority("a5");
		
		default:
			return 0;
		}	
		
	}
	
	

}
